﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.ComponentModel;
using WeiBeeCommon.Core;
using System.Windows.Forms;
using System.Threading;
using System.Linq;
using QunFaExpert.Properties;
using QunFaExpert.Data;
using System.Text.RegularExpressions;

namespace QunFaExpert
{
    /// <summary>
    /// Interaction logic for RetweetExpert.xaml
    /// </summary>
    public partial class RetweetExpert : Window
    {
        public RetweetExpert()
        {
            InitializeComponent();
            _bgwAt.WorkerReportsProgress = true;
            _bgwAt.WorkerSupportsCancellation = true;
            _bgwAt.DoWork += new DoWorkEventHandler(_bgwAt_DoWorkJob);
            _bgwAt.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bgwAt_RunWorkerCompletedJob);
            _bgwAt.ProgressChanged += new ProgressChangedEventHandler(_bgwAt_ProgressChanged);            
        }

        const int TenMinutes = 10* 60 * 1000;
        List<string> AtList = new List<string>();
        string preAt;
        string afterAt;
        private void buttonAt_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog openDlg = new Microsoft.Win32.OpenFileDialog();
            bool? file = openDlg.ShowDialog();
            if (file.HasValue && file.Value)
            {
                try
                {
                    var reader = ReaderFactory.GetInstance(openDlg.FileName);
                    AtList = reader.GetAtList(AtList);
                    AtList = AtList.Distinct().ToList();
                    System.Windows.MessageBox.Show(string.Format("账号导入成功，一共导入{0}个账号", AtList.Count));
                    labelAtCounter.Content = string.Format("共有{0}待@",AtList.Count);
                    new EntityHelper().SaveAts(AtList);
                    EnableStartAtButton();
                }
                catch(Exception exception)
                {
                    System.Windows.MessageBox.Show(string.Format("账号从文件导入失败，请检查文件格式。错误信息：{0}",exception.Message));
                }
            }
        }

        private readonly BackgroundWorker _bgwAt = new BackgroundWorker();
        private void buttonStartAt_Click(object sender, RoutedEventArgs e)
        {
            StartAt();
            tbResult.Text = string.Empty;
            buttonCancel.IsEnabled = true;
            buttonStartAt.IsEnabled = false;
            Settings.Default.AtUrl = textBoxRetweet.Text;
            Settings.Default.AfterAt = textBoxAfterAt.Text;
            Settings.Default.PreAt = textBoxPreAt.Text;
            Settings.Default.Save();
        }

        private void StartAt()
        {
            string id = (new TypedId(textBoxRetweet.Text)).id;
            preAt = textBoxPreAt.Text;
            afterAt = textBoxAfterAt.Text;

            var manager = RetweetActionManager.Instance(selected, id, AtList, textBoxPreAt.Text,textBoxAfterAt.Text);
  
            RetweetJob job = manager.GetJob();
            if (job != null)
            {
                _bgwAt.RunWorkerAsync(job as object);
            }
        }

        void _bgwAt_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            string progressString = e.UserState as string;
            tbResult.Text = progressString + Environment.NewLine + tbResult.Text;
        }

        void _bgwAt_RunWorkerCompletedJob(object sender, RunWorkerCompletedEventArgs e)
        {
            UpdateListShow();
            EnableStartAtButton();
            buttonCancel.IsEnabled = false;
            ShowCompleteReason(e);
        }

        private void ShowCompleteReason(RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                tbResult.Text = @"取消@" + tbResult.Text;
            }
            else
            {
                tbResult.Text = @"完成@" + tbResult.Text;
            }
        }

        private void UpdateListShow()
        {
            bs.ResetBindings(true);
            entities.Sort();
            new EntityHelper().SaveEntities(entities);
            entities = new EntityHelper().LoadEntities();
            entities.Sort();
            listBoxAllAccounts.ItemsSource = entities;
            new EntityHelper().SaveAts(AtList);
            labelAtCounter.Content = string.Format("共有{0}待@", AtList.Count);
        }

        private void EnableStartAtButton()
        {
            if ((AtList.Count > 0) && (selected.Count > 0) || (this.currentTweetType == WeiBeeType.Sohu && selected.Count > 0))
            {
                buttonStartAt.IsEnabled = true;
            }
            else
            {
                buttonStartAt.IsEnabled = false;
            }
        }

        void _bgwAt_DoWorkJob(object sender, DoWorkEventArgs e)
        {
            RetweetJob job = null;
            do
            {
                job = RetweetActionManager.Instance().GetJob();
                if (job != null)
                {
                    job.RetweetWeiBee.Retweet(job.RetweetId, job.Status);
                    _bgwAt.ReportProgress(1, string.Format("@{0}-{1}", job.DisplayName, job.Status));
                }
                else if (!_bgwAt.CancellationPending)
                {
                    Thread.Sleep(3000);
                }
                if (_bgwAt.CancellationPending)
                {
                    e.Cancel = true;
                }
            } while (!_bgwAt.CancellationPending && (AtList.Count > 0 || currentTweetType == WeiBeeType.Sohu));
        }

        /// <summary>
        /// WeiBo.com (maybe Unix) return format to C# DateTime
        /// </summary>
        /// <param name="p">Tue Oct 04 22:00:00 +0800 2011</param>
        /// <returns>DateTime</returns>
        public DateTime StringToDateTime(string p)
        {
            DateTime result;
            if ( !DateTime.TryParseExact(p, "ddd MMM dd HH:mm:ss zz00 yyyy", new System.Globalization.CultureInfo("en-US"), System.Globalization.DateTimeStyles.AllowWhiteSpaces, out result))
            {
                result = DateTime.Now;
            }
            return result;
        }

        private void btManage_Click(object sender, RoutedEventArgs e)
        {
            var manageWeiBeeDlg = new ManageWeiBee();
            bool? showed = manageWeiBeeDlg.ShowDialog();
            if (showed.HasValue)
            {
                InitAccounts();
            }
        }

        List<AuthEntity> entities;
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitAccounts();
        }

        private void InitAccounts()
        {
            entities = new EntityHelper().LoadEntities();
            entities.Sort();
            listBoxAllAccounts.ItemsSource = entities;
            InitSelected();
            AtList = new EntityHelper().LoadAts();
            labelAtCounter.Content = string.Format("共有{0}待@", AtList.Count);
            EnableStartAtButton();
            buttonCancel.IsEnabled = false;
            textBoxPreAt.Text = Settings.Default.PreAt;
            textBoxAfterAt.Text = Settings.Default.AfterAt;
            textBoxRetweet.Text = Settings.Default.AtUrl;
        }
        private void InitSelected()
        {
            selected = new List<AuthEntity>();
            bs.DataSource = selected;
            listBoxSelectAccounts.ItemsSource = bs;
            listBoxSelectAccounts.DisplayMemberPath = "DisplayName";
            listBoxSelectAccounts.ItemStringFormat = "@{0}";
        }

        List<AuthEntity> selected = new List<AuthEntity>();
        BindingSource bs = new BindingSource();
        private void buttonSelectOne_Click(object sender, RoutedEventArgs e)
        {
            var entityToAdd = listBoxAllAccounts.SelectedItem as AuthEntity;
            if (!selected.Contains(entityToAdd) && currentTweetType==entityToAdd.UserType)
            {
                selected.Add(entityToAdd);
                bs.ResetBindings(true);
            }
            EnableStartAtButton();
        }

        private void buttonRemoveSelected_Click(object sender, RoutedEventArgs e)
        {
            selected.Remove(listBoxSelectAccounts.SelectedItem as AuthEntity);
            bs.ResetBindings(true);
            EnableStartAtButton();
        }

        private void buttonSelectFive_Click(object sender, RoutedEventArgs e)
        {
            SelectFive();
        }

        private void SelectFive()
        {
            SelectN(5);
        }

        private void SelectN(int n)
        {
            for (int i = 0; selected.Count < n && i < entities.Count; i++)
            {
                if (!selected.Contains(entities[i]) && entities[i].ActTime <= DateTime.Now && (entities[i].UserType == currentTweetType))
                {
                    selected.Add(entities[i]);
                }
            }
            bs.ResetBindings(true);
            EnableStartAtButton();
        }

        private void buttonCancel_Click(object sender, RoutedEventArgs e)
        {
            _bgwAt.CancelAsync();
        }

        private static AsyncCallback SyncContextCallback(AsyncCallback callback)
        {
            SynchronizationContext sc = SynchronizationContext.Current;
            if (sc == null) return callback;
            return asyncResult => sc.Post(result => callback((IAsyncResult)result), asyncResult);
        }

        private void textBoxRetweet_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
        {
            Dictionary<WeiBeeType, string> weibeeNameDict = new Dictionary<WeiBeeType, string>
            {
                {WeiBeeType.Sohu,"搜狐"},
                {WeiBeeType.Sina,"新浪"},
                {WeiBeeType.QQ,  "腾讯"},
                {WeiBeeType.None,"未知"}
            };
            if (this.lbRetweetType != null)
            {
                currentTweetType = GetWeiBeeType(this.textBoxRetweet.Text);
                this.lbRetweetType.Content = weibeeNameDict[currentTweetType];
            }
        }

        WeiBeeType currentTweetType;
        private WeiBeeType GetWeiBeeType(string url)
        {
            WeiBeeType result = WeiBeeType.None;
            var sinaRegex = new Regex("weibo.com");
            var sohuRegex = new Regex("t.sohu.com");
            if (sinaRegex.IsMatch(url)) result = WeiBeeType.Sina;
            if (sohuRegex.IsMatch(url)) result = WeiBeeType.Sohu;
            return result;
        }

        private void buttonAll_Click(object sender, RoutedEventArgs e)
        {
            SelectN(entities.Count);
        }
    }
}
